package cn.exrick.xboot.modules.transport.service.impl;

import cn.exrick.xboot.common.constant.CommonConstant;
import cn.exrick.xboot.common.exception.XbootException;
import cn.exrick.xboot.modules.base.dao.UserDao;
import cn.exrick.xboot.modules.base.dao.mapper.UserRoleMapper;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.entity.UserRole;
import cn.exrick.xboot.modules.base.enums.*;
import cn.exrick.xboot.modules.transport.entity.CompanyRoutes;
import cn.exrick.xboot.modules.transport.entity.CompanyWarehouses;
import cn.exrick.xboot.modules.transport.entity.Regions;
import cn.exrick.xboot.modules.transport.mapper.CompanyRoutesMapper;
import cn.exrick.xboot.modules.transport.mapper.CompanyWarehousesMapper;
import cn.exrick.xboot.modules.transport.mapper.RegionsMapper;
import cn.exrick.xboot.modules.transport.param.DepositAmountParam;
import cn.exrick.xboot.modules.transport.param.QueryCompanyWarehousesParam;
import cn.exrick.xboot.modules.transport.param.SaveDealRecordParam;
import cn.exrick.xboot.modules.transport.param.WarehousesContactParam;
import cn.exrick.xboot.modules.transport.service.CompanyWarehousesService;
import cn.exrick.xboot.modules.transport.service.DealRecordService;
import cn.exrick.xboot.modules.transport.vo.CompanyWarehousesVo;
import cn.exrick.xboot.modules.transport.vo.DealRecordVo;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
 * 物流公司仓点信息接口实现
 * @author gj
 */
@Slf4j
@Service
@Transactional
public class CompanyWarehousesServiceImpl extends ServiceImpl<CompanyWarehousesMapper, CompanyWarehouses> implements CompanyWarehousesService {

    @Autowired
    private CompanyWarehousesMapper companyWarehousesMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private UserDao userDao;
    @Autowired
    private RegionsMapper regionsMapper;
    @Autowired
    private CompanyRoutesMapper companyRoutesMapper;
    @Autowired
    private DealRecordService dealRecordService;

    @Override
    public CompanyWarehousesVo getWarehousesById(Long id) {
        //通过mapperxml中连表查询出 物流公司名称和地区名称 联系人姓名和电话号码
        CompanyWarehousesVo companyWarehousesVo = companyWarehousesMapper.getWarehousesById(id);
        return companyWarehousesVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setContact(WarehousesContactParam param) {
        User user = null;
        //判断user是否存在，不存在抛异常
        CompanyWarehouses companyWarehouses = this.getById(param.getWarehouseId());
        Regions regions = regionsMapper.selectById(companyWarehouses.getRegionId());
        if (param.getContactId() != null) {
            user = userDao.findById(param.getContactId()).orElseThrow(() -> new XbootException("联系人不存在"));
            //如果之前存在联系人要将之前联系人仓点管理员角色删除
            if (companyWarehouses.getContactId() !=null){
                userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId,companyWarehouses.getContactId())
                       .eq(UserRole::getRoleName,regions.getRegionName() + RoleEnum.WAREHOUSE_ADMIN.getValue()));
            }
            companyWarehouses.setContactId(param.getContactId());
        }
        if (StrUtil.isNotBlank(param.getContactPersonName())) {
            companyWarehouses.setContactPersonName(param.getContactPersonName());
        }else {
            if (user != null) {
                companyWarehouses.setContactPersonName(user.getNickname());
            }
        }
        if (StrUtil.isNotBlank(param.getContactPersonPhone())) {
            companyWarehouses.setContactPersonPhone(param.getContactPersonPhone());
        }else{
            if (user != null) {
                companyWarehouses.setContactPersonPhone(user.getMobile());
            }
        }
        if (param.getContactId() != null && Objects.isNull(userRoleMapper.selectOne(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId,param.getContactId())
                .eq(UserRole::getRoleName,regions.getRegionName() + RoleEnum.WAREHOUSE_ADMIN.getValue())))){
            //给user添加WAREHOUSE_ADMIN角色,通过warehouseId查询出地区名称，给user添加地区名称+WAREHOUSE_ADMIN角色
            userRoleMapper.insert(new UserRole().setUserId(param.getContactId())
                    .setRoleName(regions.getRegionName() + RoleEnum.WAREHOUSE_ADMIN.getValue())
                    .setWarehouseId(param.getWarehouseId()));
        }
        this.saveOrUpdate(companyWarehouses);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removearehousesById(Long id) {
        CompanyWarehouses cw = companyWarehousesMapper.selectById(id);
        //判断是否有线路关联,仓点在线路用有可能是 起运仓点有可能是目的地仓点，并且要是一个公司下的，如果有抛异常
        List<CompanyRoutes> companyRoutes = companyRoutesMapper.selectList(
                new LambdaQueryWrapper<CompanyRoutes>().eq(CompanyRoutes::getCompanyId,cw.getCompanyId())
                        .and(a->a.eq(CompanyRoutes::getOriginWarehouseId, id).or().eq(CompanyRoutes::getDestinationWarehouseId, id)));
        if (CollectionUtil.isNotEmpty(companyRoutes)){
            throw new XbootException("该仓点有线路关联，无法删除");
        }
        //删除该仓点
        this.removeById(id);
        //判断是否只有一个联系人，如果只有这一个，那么移除 user的WAREHOUSE_ADMIN角色，并删除 userRole表中的相关数据
        //判断当前联系人是否只有一个仓点，如果只有这一个，那么移除 user的WAREHOUSE_ADMIN角色
        if (cw.getContactId() != null){
            Regions regions = regionsMapper.selectById(cw.getRegionId());
                userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId,cw.getContactId())
                        .eq(UserRole::getRoleName,regions.getRegionName() + RoleEnum.WAREHOUSE_ADMIN.getValue()));

        }
    }

    @Override
    public IPage<CompanyWarehousesVo> getWarehousesByCondition(Page page, QueryCompanyWarehousesParam param) {
        //通过mapper.xml连表查询出CompanyWarehousesVo中的字段，并添加QueryCompanyWarehousesParam 中的过滤条件
        return companyWarehousesMapper.getWarehousesByCondition(page, param);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CompanyWarehousesVo depositRecharge(DepositAmountParam param) {
        CompanyWarehousesVo companyWarehousesVo = new CompanyWarehousesVo();
        //更新仓点押金数，并新增公司押金明细记录
        CompanyWarehouses companyWarehouses = this.getById(param.getWarehouseId());
        if (companyWarehouses == null){
            throw new XbootException("该仓点不存在");
        }
        //生成公共支付流水信息，发起微信支付
        //发起预支付
        SaveDealRecordParam dealRecordParam = SaveDealRecordParam.builder()
                .dealType(DealTypeEnum.INCOME.getCode())
                .dealAmount(param.getAmount().multiply(new BigDecimal(100)).intValue())
                .orderId(companyWarehouses.getId())
                .orderType(DealOrderTypeEnum.DEPOSIT.getCode())
                .paymentType(PaymentTypeEnum.WECHAT.getCode())
                .wxTradeType(TradeTypeEnum.JSAPI)
                .wxAppTypeCode(WxAppTypeEnum.MA.getCode())
                .dealDescription(CommonConstant.DEAL_DESCRIPTION_REGISTRATION)
                .build();
        //未抛异常证明流程正常
        DealRecordVo dealRecordVo = dealRecordService.saveDealRecord(dealRecordParam);
        log.info("===========充值支付信息为 为:{}===========", dealRecordVo.getWechatPayInfo());
        companyWarehousesVo.setWechatPayInfo(dealRecordVo.getWechatPayInfo());
        return companyWarehousesVo;
    }
}